package com.peking.donations.plugins.pay.wx.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.peking.donations.base.util.JaxbUtil;
import com.peking.donations.base.util.Signature;
import com.peking.donations.plugins.pay.wx.constants.WxAPI;
import com.peking.donations.plugins.pay.wx.protocol.pay.UnifiedPayRepData;
import com.peking.donations.plugins.pay.wx.protocol.pay.UnifiedPayReqData;
import com.peking.donations.plugins.pay.wx.utils.Configure;
import com.peking.donations.plugins.pay.wx.utils.WxpayException;

/**
 * Created by YGR on 16/3/3.
 */
@Component(value = "unifiedPayService")
public class UnifiedPayService implements BaseService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    Configure configure;

    JaxbUtil reqJaxbParser = new JaxbUtil(UnifiedPayReqData.class);

    JaxbUtil repJaxbParser = new JaxbUtil(UnifiedPayRepData.class);

    /**
     * 调用微信统一支付API
     *
     * @param reqData
     * @return
     * @throws WxpayException
     */
    public UnifiedPayRepData sendPrepayPost(UnifiedPayReqData reqData) throws WxpayException {
        // 参数验证
        Preconditions.checkArgument(null != reqData && !Strings.isNullOrEmpty(configure.getKey()));
        reqData.setAppid(configure.getAppID());
        reqData.setMch_id(configure.getMchID());
        reqData.validate();

        // 进行签名
        try {
            String sign = Signature.getSign(reqData, configure.getKey());
            reqData.setSign(sign);
        } catch (Exception e) {
            logger.error("微信签名失败", e);
            throw new WxpayException("微信签名失败", e);
        }

        // 生成xml字符串
        String xmlData;
        try {
            xmlData = reqJaxbParser.toXml(reqData, "UTF-8");
            logger.debug("微信UNIFIED_PAY_API post数据:{}", xmlData);
        } catch (Exception e) {
            logger.error("post数据生成失败", e);
            throw new WxpayException("微信post数据生成失败", e);
        }

        // 发送请求
        ResponseEntity<String> responseEntity;
        try {
            responseEntity = restTemplate.postForEntity(WxAPI.UNIFIED_PAY_API.getApi(), xmlData, String.class);
            logger.debug("微信post 返回数据[{}]", responseEntity);
        } catch (Exception e) {
            logger.error("微信post失败", e);
            throw new WxpayException("微信post失败", e);
        }
        UnifiedPayRepData repData =repJaxbParser.fromXml(responseEntity.getBody());
        if (Strings.isNullOrEmpty(repData.return_code) || !repData.return_code.equals("SUCCESS")
                || Strings.isNullOrEmpty(repData.result_code) || repData.result_code.equals("")) {
            throw new WxpayException(String.format("微信预支付请求调用异常,returnCode[%s],resultCode[%s]", repData.return_code,
                    repData.result_code));
        }
        return repData;
    }
}
